package com.taichuan.selfcheck.hardware.mcuUpdate;

import android.content.Context;
import android.util.Log;

import com.taichuan.selfcheck.config.PropertyKey;
import com.taichuan.selfcheck.config.PropertyPreference;
import com.taichuan.selfcheck.eventbus.McuSendUpdatePackageResultEvent;
import com.taichuan.selfcheck.eventbus.McuUpdateCheckResultEvent;
import com.taichuan.serialcommunication.SerialPortPublic;
import com.taichuan.serialcommunication.mcuUpdate.base.BaseMcuUpdateClient;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

/**
 * 该类主要用于
 *
 * @author CamelLuo
 * @version 2020/5/13
 */
public class VankeSiteBoxMcuUpdateClient extends BaseMcuUpdateClient {
    private static final String TAG = VankeSiteBoxMcuUpdateClient.class.getSimpleName();

    public VankeSiteBoxMcuUpdateClient(Context mApplicationContext) {
        super(mApplicationContext);
        /**
         * 【【【重要提示】】】
         * 【【【重要提示】】】
         * 【【【重要提示】】】
         * 当设备单片机程序升级失败，并且人工复位上电进入到紧急备用程序时
         * 如果设备遭遇了【设备已被人为退出登录，卸载，重新安装或遭到破坏】 将会导致发布新的升级推送后也仍然无法
         * 【判断依据为设备的Sharepreferes文件中没有存储升级失败的单片机程序文件名】
         * 正常升级新的单片机程序的问题，此时应手动打开该行代码，让设备在执行流程前将 单片机升级程序文件名写入到Sharepreferences
         * 以达到紧急升级的效果
         * 本代码在此处为紧急情况下开启使用，单次有效，设备修复完毕请注释该行代码
         */
//        saveUpdateFileNameToSpForError();
    }

    /**
     * 单片机升级程序在assest文件夹下的存放路径
     *
     * @return
     */
    @Override
    public String getMcuUpdateFileAssetsDir() {
        return "mcuUpgrate/VankeSiteBox/";
    }

    /**
     * 单片机升级程序文件的文件名（如果没有单片机程序需要升级，文件名返回“无”即可）
     * 【重要提示】单片机程序命名必须按照 设备型号@版本号来命名，否则无法解析
     * 例: TC-U9D-L10-LK@1.0.3.bin,  TC-U9D-L10-LK@1.0.4.bin
     *
     * @return
     */
    @Override
    public String getMcuUpdateFileAssetsName() {
        return "TC-Y9D-A100@1.0.1.bin";
    }

    @Override
    protected void saveUpdateFileNameToSp() {
        PropertyPreference.get().set(PropertyKey.CFG_MCU_UPDATE_FILE_NAME, getMcuUpdateFileAssetsName());
    }

    @Override
    protected String getUpdateFileNameFormSp() {
        return PropertyPreference.get().getString(PropertyKey.CFG_MCU_UPDATE_FILE_NAME);
    }

    @Override
    protected void saveUpdateFileNameToSpForError() {
        PropertyPreference.get().set(PropertyKey.CFG_MCU_UPDATE_FILE_NAME, "紧急修复@9.9.9.bin");
    }

    @Override
    protected void registerMcuUpdateEvent() {
        //注册EventBus事件
        EventBus.getDefault().register(VankeSiteBoxMcuUpdateClient.this);
        Log.e(TAG, "registerMcuUpdateEvent: 注册单片机程序升级相关订阅事件");
    }

    @Override
    protected void unRegisterMcuUpdateEvent() {
        if (EventBus.getDefault().isRegistered(VankeSiteBoxMcuUpdateClient.this)){
            EventBus.getDefault().unregister(VankeSiteBoxMcuUpdateClient.this);
            Log.e(TAG, "registerMcuUpdateEvent: 注销单片机程序升级相关订阅事件");
        }
    }

    @Override
    protected void sendMcuUpdateCheckCmd(byte[] version) {
        SerialPortPublic.checkMcuCanUpdate(version);
        //发布指令回复超时任务
        postCheckCmdTimeoutEvent();
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void receiveMcuUpdateCheckResultEvent(McuUpdateCheckResultEvent event) {
        if (event != null) {
            int mcuCheckUpdateType = event.getMcuCheckUpdateType();
            Log.e(TAG, "McuUpdateCheckSubscription: 接收到单片机回复 能否进行单片机程序升级结果：  " + mcuCheckUpdateType);
            receiveMcuUpdateCheckEvent(mcuCheckUpdateType);
        }
    }

    @Override
    protected void sendMcuUpdatePackageCmd(int totalPackageCount, int currentPackageNum, byte[] packageData) {
        try {
            //休眠1000ms再进行发送，防止发送间隔过短导致单片机处理不过来
            Thread.sleep(1000);
            SerialPortPublic.sendMcuUpdatePackage(totalPackageCount, currentPackageNum, packageData);
            //发布指令回复超时任务
            postPackageCmdTimeoutEvent();
            Log.e(TAG, "sendMcuUpdatePackageCmd: 待发送的升级包内容数据长度为： " + packageData.length);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void receiveMcuSendUpdatePackageResultEvent(McuSendUpdatePackageResultEvent event) {
        if (event != null) {
            Log.e(TAG, "mcuSendUpdatePackageResultSubscription: 接收到单片机回复 当前包序号为【" +
                    event.getCurrentPackageNum() + " / " + event.getTotalPackageCount() + " 】的数据升级包结果：  " + event.getReceiveResultType());
            receiveMcuPackageSendResultEvent(BaseMcuUpdateClient.UPDATE_SEND_RESULT_TYPE_SUCESS, event.getTotalPackageCount(), event.getCurrentPackageNum());
        }
    }
}
